﻿using System;
using System.Data;
using System.Data.Common;
using MapDownloader.Core.MapProviders;
using MapDownloader.Core.Models;
using MySql.Data.MySqlClient;

namespace MapDownloader.Core.Storage
{
   /// <summary>
   ///    MySQL存储
   /// </summary>
   internal class MySqlTileStorage : ITileStore
   {
      /// <summary>
      ///    多线程时候，应该使用自旋锁
      /// </summary>
      private static volatile bool _initialized;

      private static string _connectionString = string.Empty;
      

      public void SetConnectionString(string con,string databaseName)
      {
         if (_connectionString != con)
         {
            _connectionString = con;
            if (!_initialized)
               Initialize();
         }
      }

      private int ExecuteSql(string sqlString, DbParameter[] cmdParms)
      {
         using (var connection =new  MySqlConnection(_connectionString))
         {
            using (var cmd = connection.CreateCommand())
            {
               cmd.Connection = connection;
               cmd.CommandText = sqlString;
               cmd.CommandType = CommandType.Text; //cmdType;
               try
               {
                  if (connection.State != ConnectionState.Open)
                     connection.Open();
                  if(cmdParms!=null)
                  cmd.Parameters.AddRange(cmdParms); //cmd.Parameters.Add(parm);
                  var rows = cmd.ExecuteNonQuery();
                  cmd.Parameters.Clear();
                  return rows;
               }
               catch (DbException ex)
               {
                  connection.Close();
                  connection.Dispose();
                  throw new Exception(ex.Message);
               }
            }
         }
      }

      /// <summary>
      ///    存储初始化
      /// </summary>
      public bool Initialized
      {
         get => _initialized;
      }

      /// <summary>
      ///    初始化
      /// </summary>
      /// <returns></returns>
      public bool Initialize()
      {
         if (!_initialized)
         {
            try
            {
               var createSql = @" CREATE TABLE IF NOT EXISTS `tab_map` (
`Type` int(10) NOT NULL,
                             `Zoom` int(10) NOT NULL,
                             `X` int(10) NOT NULL,
                             `Y` int(10) NOT NULL,
                             `Tile` longblob NOT NULL,
                             PRIMARY KEY (`Zoom`,`X`,`Y`)
                           ) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
               ExecuteSql(createSql, null);
               _initialized = true;
            }
            catch (Exception e)
            {
               Console.WriteLine($"创建表失败:{e.Message}");
            } 
         }

         return _initialized;
      }


      #region 继承于接口

      public bool PutTileToStore(int type,TilePoint pos, byte[] tile)
      {
         if (Initialize())
         {
            var sql = "INSERT INTO `tab_map` ( Type,Zoom, X, Y, Tile ) VALUES ( @type,@zoom, @x, @y, @tile )";
            var cmdParms = new DbParameter[5];
            cmdParms[0] = new MySqlParameter("@tile", tile);
            cmdParms[1] = new MySqlParameter("@zoom", pos.Z);
            cmdParms[2] = new MySqlParameter("@x", pos.X);
            cmdParms[3] = new MySqlParameter("@y", pos.Y);
            cmdParms[4] = new MySqlParameter("@type", type);
            return ExecuteSql(sql, cmdParms) > 0;
         }

         return false;
      }

      public int DeleteOlderThan(DateTime date, int? type)
      {
         throw new NotImplementedException();
      }
      /// <summary>
      /// 从数据中获取一条记录
      /// </summary>
      /// <param name="x"></param>
      /// <param name="y"></param>
      /// <param name="zoom"></param>
      /// <param name="type">瓦片类型</param>
      /// <returns></returns>
      public BaseImage GetTileFromStore(long x, long y, int zoom,int type)
      {
         var sqlString = $"SELECT Tile FROM `tab_map` WHERE  Zoom={zoom} AND X={x} AND Y={y} AND type={type}";
         BaseImage result = null;
         try
         {
            object data;
            using (var connection = new MySqlConnection(_connectionString))
            {
               using (var cmd = connection.CreateCommand())
               {
                  cmd.Connection = connection;
                  cmd.CommandText = sqlString;
                  try
                  {
                     connection.Open();
                     data = cmd.ExecuteScalar();
                  }
                  finally
                  {
                     connection.Close();
                     connection.Dispose();
                  }
               }
            }

            if (data != null && data != DBNull.Value)
            {
               var tile = (byte[])data;
               if (tile.Length > 0)
                  if (BaseMapProvider.TileImageProxy != null)
                     result = BaseMapProvider.TileImageProxy.FromArray(tile);
            }

            return result;
         }
         catch (Exception e)
         {
            throw new Exception("查询失败", e);
         }
      }

      #endregion
   }
}